package com.sias.reflection;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author 吴文杰
 * @version 1.0
 * @createTime 2023-05-02 16:30:14
 */
@SuppressWarnings("all")
public class ReflectCreateInstance {
  /**
   * 1.方式一：调用类中的public修饰的无参构造器
   * 2.方式二：调用类中的指定构造器
   * 3.Class类相关方法：
   *    newInstance：调用类的无参构造器，获取对应类的对象
   *    getConstructor(Class...clazz)：根据参数列表，获取对应的构造器对象
   *    getDeclaredConstructor(Class...clazz)：根据参数列表，获取对应的构造器对象
   * 4.Constructor类相关方法：
   *    setAccessible：爆破
   *    newInstance(Object...obj)：调用构造器
   */
  public static void main(String[] args) throws Exception {
    //1.获取User类的Class对象
    Class<?> cls = Class.forName("com.sias.reflection.User");
    //2.通过public的无参构造器创建实例
    Object o = cls.newInstance();
    //3.通过public的有参构造器创建实例
    Constructor<?> constructor = cls.getConstructor(String.class);
    Object user = constructor.newInstance("user");
    System.out.println("User="+user);
    //4.通过非public的有参构造器创建实例
    Constructor<?> allArgsConstructor = cls.getDeclaredConstructor(int.class, String.class);
    allArgsConstructor.setAccessible(true);
    Object wwj = allArgsConstructor.newInstance(10, "吴文杰");
    System.out.println(wwj);

  }

  @Test
  public void test() throws Exception {
    Class<?> cls = Class.forName("com.sias.reflection.User");
    Object o = cls.newInstance();
    Field name = cls.getDeclaredField("name");
    name.setAccessible(true);
    name.set(o,"wwj");
    System.out.println(o);

    Method m1 = cls.getMethod("m1");
    m1.invoke(o);
    Method m2 = cls.getDeclaredMethod("m2");
    m2.setAccessible(true);
    m2.invoke(o);

    Method m3 = cls.getDeclaredMethod("m3");
    m3.setAccessible(true);
    m3.invoke(null);

    Method m4 = cls.getDeclaredMethod("m4",String.class);
    m4.setAccessible(true);
    m4.invoke(null,"吴文杰");

    Method m5 = cls.getDeclaredMethod("m5",String.class);
    m5.setAccessible(true);
    Object invoke = m5.invoke(null, "吴文杰");
    System.out.println(invoke.getClass()+"\t"+invoke);
  }
}

class User {
  private int age;
  private String name;

  public User() {
  }

  public User(String name){
    this.name = name;
  }

  private User(int age, String name) {
    this.age = age;
    this.name = name;
  }
  public void m1(){
    System.out.println("m1");
  }
  private void m2(){
    System.out.println("m2");
  }
  private static void m3(){
    System.out.println("m3");
  }
  private static void m4(String name){
    System.out.println("m4:"+name);
  }

  private static String m5(String name){
    return name;
  }

  public String toString() {
    return "User [age=" + age + ",name=" + name + "]";
  }
}